﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Controls.DataVisualization.Charting;
using SqlMiM.Common.UserControls;
using System.ComponentModel;
using SqlMiM.Common.Controls;
using System.Diagnostics;
using System.Windows.Threading;
using SqlMiM.Common.UserControls.PerfGraph;

namespace SqlMiM.SqlServer.Server2008
{
    /// <summary>
    /// Interaction logic for View.xaml
    /// </summary>
    public partial class View : UserControl
    {
        private ViewModel viewModel;
        private HistoryData frameUserConnections;
        private HistoryData frameLoginsSec;
        private HistoryGraphGroup _historyGraphGroup;
        private DispatcherTimer timer;


        public View()
        {
            InitializeComponent();

            //viewModel = new ViewModel();
            //this.DataContext = viewModel;

            this._historyGraphGroup = new HistoryGraphGroup((TimeSpan)this.FindResource("updateInterval"));

            this._historyGraphGroup.ClearData();

            this.InitializeHistoryData();

            this._historyGraphGroup.Add(userConnectionsGraph);
            
            this._historyGraphGroup.Start();

            BackgroundWorker bw = new BackgroundWorker();

            bw.DoWork += (sender, args) => { this.SetUpPerformanceCounters(); };

            bw.RunWorkerCompleted += (sender, args) =>
            {
                this.timer = new DispatcherTimer((TimeSpan)this.FindResource("updateInterval"), DispatcherPriority.Background, new EventHandler(GetPerfs_DoWork), Dispatcher.CurrentDispatcher);
            };

            bw.RunWorkerAsync();


        }

        /// <summary>
        /// Init
        /// </summary>
        private void InitializeHistoryData()
        {
            this.frameUserConnections = new HistoryData("UserConnections", this.userConnectionsGraph.GraphDuration);
            this.frameUserConnections.Fill = (Brush)base.FindResource("UserConnectionsFill");
            this.frameUserConnections.Stroke = new Pen((Brush)base.FindResource("UserConnectionsPen"), 0.1d);
            this.frameUserConnections.Type = HistoryDataType.Path;
            this.userConnectionsGraph.AddHistoryData(frameUserConnections);

            this.frameLoginsSec = new HistoryData("LoginsSec", this.userConnectionsGraph.GraphDuration);
            this.frameLoginsSec.Fill = (Brush)base.FindResource("UserConnectionsFill");
            this.frameLoginsSec.Stroke = new Pen((Brush)base.FindResource("UserConnectionsPen"), 0.2d);
            this.frameLoginsSec.Type = HistoryDataType.Shape;
            this.userConnectionsGraph.AddHistoryData(frameLoginsSec);

            this.userConnectionsGraph.Group = this._historyGraphGroup;

            this.userConnectionsGraph.VerticalAxisConverter = new ValueToLabelHandler(this.RemoveDataMultiplier);
            this.userConnectionsGraph.PropertyChanged += new PropertyChangedEventHandler(this.HistoryGraphPropertyChanged);
            
        }

        private PerformanceCounter[] perfCounters = new PerformanceCounter[10];
        private void SetUpPerformanceCounters()
        {
            this.perfCounters = new PerformanceCounter[2];
            this.perfCounters[0] = new PerformanceCounter("MSSQL$SQL2008:General Statistics", "User Connections");
            this.perfCounters[1] = new PerformanceCounter("MSSQL$SQL2008:General Statistics", "Logins/sec");
        }


        /// <summary>
        /// Workaround to scroll over listboxs
        /// </summary>
        private void scroll_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (e.Source as ItemsControl != null)
            {
                //scroll.ScrollToVerticalOffset(scroll.VerticalOffset - e.Delta);
                e.Handled = true;
            }
        }



        private void GetPerfs_DoWork(object sender, EventArgs e)
        {
            if (this.perfCounters == null || this.perfCounters.Length == 0)
                return;

            foreach (PerformanceCounter p in this.perfCounters)
            {
                var time = DateTime.Now.Second;
                var number = (double)p.NextValue();

                DateTime utcNow = DateTime.UtcNow;

                if (p.CounterName == "User Connections")
                    this.frameUserConnections.AddData(utcNow, number);

                if (p.CounterName == "Logins/sec")
                    this.frameLoginsSec.AddData(utcNow, number);


            }

        }


        private void HistoryGraphPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            HistoryGraph historyGraph = (HistoryGraph)sender;
            string propertyName = e.PropertyName;
            if (propertyName != null)
            {
                if (!(propertyName == "YMaxValue"))
                {
                    if (!(propertyName == "VisibleInterval"))
                    {
                        return;
                    }
                }
                else
                {
                  //  this.UpdateValueIntervals(historyGraph);
                    return;
                }
                this.UpdateTimeIntervals(historyGraph);
            }
        }

        private void UpdateValueIntervals(HistoryGraph historyGraph)
        {
            int num4;
            double yMaxValue = historyGraph.YMaxValue;
            int num2 = (int)Math.Pow(10.0, (double)((int)Math.Log10(yMaxValue)));
            double num3 = yMaxValue / ((double)num2);
            if (num3 > 6.0)
            {
                num4 = num2 * 2;
            }
            else if (num3 > 2.0)
            {
                num4 = num2;
            }
            else
            {
                num4 = num2 / 2;
            }
            historyGraph.MajorValueInterval = Math.Max(num4, 100);
            historyGraph.MinorValueInterval = Math.Max(num4 / 5, 100);
        }


        private void UpdateTimeIntervals(HistoryGraph historyGraph)
        {
            int num4;
            double totalSeconds = historyGraph.VisibleInterval.TotalSeconds;

            int num2 = (int)Math.Pow(10.0, (double)((int)Math.Log10(totalSeconds)));

            double num3 = totalSeconds / ((double)num2);

            if (num3 > 6.0)
            {
                num4 = num2 * 2;
            }
            else if (num3 > 2.0)
            {
                num4 = num2;
            }
            else
            {
                num4 = num2 / 2;
            }

            historyGraph.MajorTimeInterval = TimeSpan.FromSeconds((double)Math.Max(num4, 1));
            historyGraph.MinorTimeInterval = TimeSpan.FromSeconds((double)Math.Max(num4 / 5, 1));
        }








        private string RemoveDataMultiplier(double value)
        {
            value /= 100.0;
            return value.ToString();
        }









        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {

        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
        }

        private void btnZoomIn_Click(object sender, RoutedEventArgs e)
        {
            userConnectionsGraph.Width += 20d;
            userConnectionsGraph.Height += 20d;


        }

        private void btnZoomOut_Click(object sender, RoutedEventArgs e)
        {
            if (userConnectionsGraph.Width > 120d && userConnectionsGraph.Height > 70d)
            {
                userConnectionsGraph.Width -= 20d;
                userConnectionsGraph.Height -= 20d;
            }

        }

    }
}
